import { PositionMeta, ColorMeta, Meta, MetaCombine } from "./Meta";

type MatrixChange = [PositionMeta, ColorMeta][];
/** 一个图层的历史数据 */
export class DataController {
    history: Meta[] = [];
    /** 用于撤销操作时生成的临时分支 */
    private tempBranch: Meta[] = [];
    constructor(history: Meta[]) {
        this.history = history;
    }
    /** 保存一个元数据 */
    save(meta: Meta) {
        this.history.push(meta);
        // 当产生一个新数据时，tempBranch 中的数据就不需要了
        this.tempBranch = [];
    }
    /** 撤销一个元数据 */
    cancel(step = 1): MatrixChange {
        // 将 history 中的步骤移入 tempBranch
        const tempHistory = this.history.splice(
            this.history.length - step,
            step
        );
        this.tempBranch.unshift(...tempHistory);
        const command = this.combineHistory(tempHistory);
        return command.change.map(({ position, diff: [oldVal] }) => {
            return [position, oldVal];
        });
    }
    /** 组合所有的历史记录为一个 Meta */
    combineHistory(history: Meta[]) {
        const collection = new MetaCombine();
        return history.reduce((col, cur) => {
            cur.addTo(col);
            return col;
        }, collection);
    }

    /** 恢复一个撤销 */
    recover(step = 1): MatrixChange {
        // 将 tempBranch 中的数据移入 history
        const tempHistory = this.tempBranch.splice(0, step);
        this.history.push(...tempHistory);
        const command = this.combineHistory(tempHistory);
        return command.change.map(({ position, diff: [_, val] }) => {
            return [position, val];
        });
    }
    /** 从对象中重构 */
    reCreate(data: Meta[]) {
        this.history = data;
        return this.combineHistory(data);
    }
    /** 定义持久化方式 */
    toString() {
        return JSON.stringify(this.history);
    }
}
